%%% функции ввода вывода графа
-module(io_graph).
-export([load_graph/1, print_cliq/2, get_V/1]).
-include("graph.hrl").

get_V(File) ->
    {ok, FileId} = file:open(File, [read, binary]),
    {ok, Binary} = file:read(FileId,2),
   <<Nodes:2/little-unsigned-integer-unit:8>> = Binary,
    Nodes.

%%% загрузка графа из файла
%% реализован конечным автоматом
%% загрузка из текстового файла
load_graph({text, File})->
    io:format("Open file ~s ~n", [File]),
    {ok, IoDevice} = file:open(File,[read]),
    load_graph_a({text, nodes, IoDevice, graph:new() });

%% загрузка из бинарного файла
load_graph({binary, File})->
    io:format("Open file ~s ~n", [File]),
    {ok, FileId} = file:open(File, [read, binary]),
    load_graph_a({binary, nodes, FileId, graph:new() }).

%%% загрузка вершин
load_graph_a({text, nodes, Device, Graph})->
    case io:get_line(Device, "") of
	eof->
	    io:format("Error: Invelid file format! ~n");
	Str-> case re:run(Str, "\s*#+") of
		  {match, [_]} ->
		      N = lists:last(graph:v(Graph)),
		      load_graph_a({text,
				    edges,
				    Device,
				    graph:new(graph:v(Graph),
					      array:new([{size, N+1},
							{default,[]}]))});
		  nomatch ->
		      {Node,_} = string:to_integer(Str),
		      load_graph_a({text, nodes, Device, graph:new(lists:append(graph:v(Graph),[Node]),
								   array:new())})
	     end
   end;

load_graph_a({binary, nodes, FileId, _})->
    {ok, Binary} = file:read(FileId, 2),
   <<Nodes:2/little-unsigned-integer-unit:8>> = Binary,
    load_graph_a({binary, edges, FileId, create_empty_graph(Nodes)});
    

%%% загрузка ребер
load_graph_a({text, edges,Device, Graph}) ->
    case io:get_line(Device, "") of
	eof ->
%	     sort_edges(Graph);
	    Graph;
	Str -> [Node1, Node2] = re:split(Str, " ", [{return, list}]),
	       {N1,_} = string:to_integer(Node1),
	       {N2,_} = string:to_integer(Node2),
	       load_graph_a({text, edges, Device, graph:add_edge_in_orgraph({N1,N2},
									    Graph)})
   end;

%%%загрузка ребер из бинарного файло
load_graph_a({binary, edges, FileId, Graph}) ->
    case file:read(FileId, 4) of
	eof ->
	    Graph;
	{error, Reason} ->
	    io:format("Error load Data ~s ~n",[Reason]);
	{ok, Binary} ->
	    <<V1:2/little-unsigned-integer-unit:8, V2:2/little-unsigned-integer-unit:8>> = Binary,
	    NG = graph:add_edge_in_orgraph({V2, V1},
					   Graph),
	    load_graph_a({binary, edges, FileId, graph:add_edge_in_orgraph({V1,V2},
									  NG)})
    end.
	    

%%% сортировка списков смежностей
%sort_edges(G)->
%    sort_edges(graph:v(G), G, dict:new() ).
%%% список вершин, граф, словарь
%sort_edges([],G,N)->
%    graph:new( graph:v(G), N );
%sort_edges([Head|Tail], G, N)->
%    sort_edges( Tail, G, dict:append_list(Head, lists:sort( graph:adj(Head,G) ), N)).

%вывод клика на консоль
print_cliq(S,_)->
    io:format(" ~w ~n",[S]).


%% создает пустой граф с множествами вершин Nodes
create_empty_graph(Nodes)->
    create_empty_graph(1, Nodes, graph:new([1],
					   array:new([{default, []}]))).

create_empty_graph(Nodes, Nodes, Graph)->
    graph:new(graph:v(Graph)++[Nodes],
	      graph:get_array(Graph));

create_empty_graph(V, Nodes, Graph) ->
    create_empty_graph(V+1, Nodes,
		       graph:new(graph:v(Graph)++[V],
				 graph:get_array(Graph))).
